package com.xcity.game.combat.template;

import com.xcity.game.combat.attr.CombatAttribute;
import com.xcity.game.combat.attr.CombatAttributeType;

import naga.x.game.template.Template;
import naga.x.game.template.TemplateException;
import naga.x.game.template.annotation.Excel;

/**
 * 战斗属性
 * @author yang.li
 *
 */
@Excel(value = "combat.xlsx", sheet = 0)
public class CombatAttributeTemplate extends Template {

	/** 物攻 */
	protected float attackPower;

	/** 法攻 */
	protected float magicPower;

	/** 物防 */
	protected float defense;

	/** 法防 */
	protected float magicDefense;

	/** 生命值 */
	protected float hp;

	/** 韧性 */
	protected float avoidCrit;

	/** 速度 */
	protected float attackSpeed;

	/** 闪避 */
	protected float dodge;

	/** 抵抗 */
	protected float resist;

	/** 物攻命中 */
	protected float hitRate;

	/** 法攻命中 */
	protected float magicHitRate;

	/** 暴击 */
	protected float crit;

	/** 物攻成长 */
	protected float attackPowerDelta;

	/** 法攻成长 */
	protected float magicPowerDelta;

	/** 物防成长 */
	protected float defenseDelta;

	/** 法防成长 */
	protected float magicDefenseDelta;

	/** 生命值成长 */
	protected float hpDelta;

	/** 韧性成长 */
	protected float avoidCritDelta;

	/** 速度成长 */
	protected float attackSpeedDelta;

	/** 闪避成长 */
	protected float dodgeDelta;

	/** 抵抗成长 */
	protected float resistDelta;

	/** 物攻命中成长 */
	protected float hitRateDelta;

	/** 法攻命中成长 */
	protected float magicHitRateDelta;

	/** 暴击成长 */
	protected float critDelta;
	
	private Wrapper[] attrs;
	
	static class Wrapper extends CombatAttribute {
		float delta;
		Wrapper(CombatAttributeType type, float value, float delta) {
			super(type, value);
			this.delta = delta;
		}
	}

	public float getAttackPower() {
		return attackPower;
	}

	public void setAttackPower(float attackPower) {
		this.attackPower = attackPower;
	}

	public float getMagicPower() {
		return magicPower;
	}

	public void setMagicPower(float magicPower) {
		this.magicPower = magicPower;
	}

	public float getDefense() {
		return defense;
	}

	public void setDefense(float defense) {
		this.defense = defense;
	}

	public float getMagicDefense() {
		return magicDefense;
	}

	public void setMagicDefense(float magicDefense) {
		this.magicDefense = magicDefense;
	}

	public float getHp() {
		return hp;
	}

	public void setHp(float hp) {
		this.hp = hp;
	}

	public float getAvoidCrit() {
		return avoidCrit;
	}

	public void setAvoidCrit(float avoidCrit) {
		this.avoidCrit = avoidCrit;
	}

	public float getAttackSpeed() {
		return attackSpeed;
	}

	public void setAttackSpeed(float attackSpeed) {
		this.attackSpeed = attackSpeed;
	}

	public float getDodge() {
		return dodge;
	}

	public void setDodge(float dodge) {
		this.dodge = dodge;
	}

	public float getResist() {
		return resist;
	}

	public void setResist(float resist) {
		this.resist = resist;
	}

	public float getHitRate() {
		return hitRate;
	}

	public void setHitRate(float hitRate) {
		this.hitRate = hitRate;
	}

	public float getMagicHitRate() {
		return magicHitRate;
	}

	public void setMagicHitRate(float magicHitRate) {
		this.magicHitRate = magicHitRate;
	}

	public float getCrit() {
		return crit;
	}

	public void setCrit(float crit) {
		this.crit = crit;
	}

	public float getAttackPowerDelta() {
		return attackPowerDelta;
	}

	public void setAttackPowerDelta(float attackPowerDelta) {
		this.attackPowerDelta = attackPowerDelta;
	}

	public float getMagicPowerDelta() {
		return magicPowerDelta;
	}

	public void setMagicPowerDelta(float magicPowerDelta) {
		this.magicPowerDelta = magicPowerDelta;
	}

	public float getDefenseDelta() {
		return defenseDelta;
	}

	public void setDefenseDelta(float defenseDelta) {
		this.defenseDelta = defenseDelta;
	}

	public float getMagicDefenseDelta() {
		return magicDefenseDelta;
	}

	public void setMagicDefenseDelta(float magicDefenseDelta) {
		this.magicDefenseDelta = magicDefenseDelta;
	}

	public float getHpDelta() {
		return hpDelta;
	}

	public void setHpDelta(float hpDelta) {
		this.hpDelta = hpDelta;
	}

	public float getAvoidCritDelta() {
		return avoidCritDelta;
	}

	public void setAvoidCritDelta(float avoidCritDelta) {
		this.avoidCritDelta = avoidCritDelta;
	}

	public float getAttackSpeedDelta() {
		return attackSpeedDelta;
	}

	public void setAttackSpeedDelta(float attackSpeedDelta) {
		this.attackSpeedDelta = attackSpeedDelta;
	}

	public float getDodgeDelta() {
		return dodgeDelta;
	}

	public void setDodgeDelta(float dodgeDelta) {
		this.dodgeDelta = dodgeDelta;
	}

	public float getResistDelta() {
		return resistDelta;
	}

	public void setResistDelta(float resistDelta) {
		this.resistDelta = resistDelta;
	}

	public float getHitRateDelta() {
		return hitRateDelta;
	}

	public void setHitRateDelta(float hitRateDelta) {
		this.hitRateDelta = hitRateDelta;
	}

	public float getMagicHitRateDelta() {
		return magicHitRateDelta;
	}

	public void setMagicHitRateDelta(float magicHitRateDelta) {
		this.magicHitRateDelta = magicHitRateDelta;
	}

	public float getCritDelta() {
		return critDelta;
	}

	public void setCritDelta(float critDelta) {
		this.critDelta = critDelta;
	}

	public float calc(CombatAttributeType type, int level) {
		Wrapper attr = attrs[type.ordinal()];
		if (attr != null) {
			return attr.getValue() + (level - 1) * attr.delta;
		}
		return 0f;
	}

	@Override
	public void validate() throws TemplateException {
		float[] vals = new float[] {
				attackPower, magicPower, defense, magicDefense,
				crit, avoidCrit, hp, attackSpeed,
				0f/*CRIT_DAMAGE*/, 0f/*MP*/, 0f/*MAX_HP*/, 0f/*MAX_MP*/,
				dodge, resist, hitRate, magicHitRate
		};
		float[] deltas = new float[] {
				attackPowerDelta, magicPowerDelta, defenseDelta, magicDefenseDelta,
				critDelta, avoidCritDelta, hpDelta, attackSpeedDelta,
				0f/*CRIT_DAMAGE*/, 0f/*MP*/, 0f/*MAX_HP*/, 0f/*MAX_MP*/,
				dodgeDelta, resistDelta, hitRateDelta, magicHitRateDelta
		};
		CombatAttributeType[] types = CombatAttributeType.vals;
		int len = types.length;
		Wrapper[] attrs = new Wrapper[len];
		for (int i = 0; i < len; i++) {
			float val = vals[i];
			float delta = deltas[i];
			if (val > 0 && delta > 0) {
				attrs[i] = new Wrapper(types[i], val, delta);
			}
		}
		this.attrs = attrs;
		vals = deltas = null;
	}
}
